/**
 * Copyright (C) 2021 - 2031 O-Cubes Co., Ltd.
 */

/****************************************************************
 *  @file    hal_api.h
 *  @brief   HAL layer interface header file
 *  @version v1.0
 *  @date    03. Apr. 2023
 ****************************************************************/

#ifndef __HAL_API_H__
#define __HAL_API_H__

/*
 * INCLUDE FILES
 ****************************************************************************************
 */
#include <stdint.h>
#include <stdbool.h>

#include "datetime.h"
#include "dev_gpio.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "queue.h"

#ifdef __cplusplus
extern "C" {
#endif

/// Convert milliseconds to FreeRTOS systick number
#define HAL_MS_TO_TICKS(xTimeInMs)   pdMS_TO_TICKS( xTimeInMs )
#define SEC_KEY_LEN                  16
#define MNT_SMP_CHANNEL_NUM          18
#define MNT_ARC_RESULT_NUM           4

/**
 ****************************************************************************************
 * @defgroup HAL_API Hardware Adapter Layer APIs
 * @brief Description of Hardware Adapter Layer APIs
 * @{
 ****************************************************************************************
 */

/*
 * DEFINES
 ****************************************************************************************
 */
/// Pad Definition
typedef uint32_t Pad_Id_t;
/// SYSCNT Timestamp Definition
typedef uint64_t Sys_Timestamp_t;
/// Interrupt ID Definition
typedef uint32_t Irq_Num_t;
/// I2C Address Definition
typedef uint16_t I2c_Addr_t;
/// Flash Address Definition
typedef uint32_t Flash_Addr_t;
/// DMA Channel Definition
typedef int32_t dma_chan_t;
/// DMA Operation Address
typedef unsigned long dma_addr_t;
/// DMA Transfer Direction
typedef int32_t dma_dir_t;
/// DMA Burst Size
typedef uint8_t dma_burst_size_t;
/// DMA Ack Bytes
typedef uint8_t dma_ack_bytes_t;
/// DMA Slave ID
typedef uint8_t dma_slave_id_t;
/// DMA Priority
typedef uint8_t dma_priority_t;
/// DMA Channel Mask
typedef uint8_t dma_chan_mask_t;
/*
 * MACROS
 ****************************************************************************************
 */
/// OK definition
#define RET_OK                         (0)
/// Failed definition
#define RET_FAILED                     (-1)

/*
 * ENUMERATIONS
 ****************************************************************************************
 */

/// List of GPIO pin values
typedef enum {
	/// GPIO pin level low
	GPIO_PIN_ACTIVE_LOW,
	/// GPIO pin level high
	GPIO_PIN_ACTIVE_HIGH,
} Gpio_Pin_Val;

/// List of GPIO Pin ID
typedef enum {
	GPIO_00, GPIO_01, GPIO_02, GPIO_03,
	GPIO_04, GPIO_05, GPIO_06, GPIO_07,
	GPIO_08, GPIO_09, GPIO_10, GPIO_11,
	GPIO_12, GPIO_13, GPIO_14, GPIO_15,
	GPIO_16, GPIO_17, GPIO_18, GPIO_19,
	GPIO_20, GPIO_21, GPIO_22, GPIO_23,
	GPIO_24, GPIO_25, GPIO_26, GPIO_27,
	GPIO_28, GPIO_29, GPIO_30, GPIO_31,
} Gpio_Pin;

typedef enum {
	GPIO_PORT_A,
	GPIO_PORT_B,
} Gpio_Port;


/// List of PCL pin func select
typedef enum {
	/// PCL pin function select 1
	PCL_PIN_FUNC_SEL_1,
	/// PCL pin function select 2
	PCL_PIN_FUNC_SEL_2,
	/// PCL pin function select 3
	PCL_PIN_FUNC_SEL_3,
	/// PCL pin function select 4
	PCL_PIN_FUNC_SEL_4,
	/// PCL pin function select 5
	PCL_PIN_FUNC_SEL_5,
	/// PCL pin function select 6
	PCL_PIN_FUNC_SEL_6,
} Pcl_Pin_Func;

/// List of PCL Pull-down Pull-up configure
typedef enum {
	/// PCL Pull-down Pull-up Enable
	PCL_PD_PU_ENABLE,
	/// PCL Pull-down Pull-up Disable
	PCL_PD_PU_DISABLE,
} Pcl_Pd_Pu_Set;

/// List of PCL PIN output configure
typedef enum {
	/// PCL PIN output Enable
	PCL_OUTPUT_ENABLE,
	/// PCL PIN output Disable
	PCL_OUTPUT_DISABLE,
} Pcl_Output_Set;

/// List of Timer ID
typedef enum {
	/// Timer ID 0
	TIMER_ID_0,
	/// Timer ID 1
	TIMER_ID_1,
	/// Timer ID 2
	TIMER_ID_2,
	/// Timer ID 3
	TIMER_ID_3,
	/// Timer ID 4
	TIMER_ID_4,
	/// Timer ID 5
	TIMER_ID_5,
} Timer_Id;

/// List of PWM ID
typedef enum {
	/// PWM ID 0
	PWM_ID_0,
	/// PWM ID 1
	PWM_ID_1,
} Pwm_Id;

/// List of WDT ID
typedef enum {
	/// WDT ID 0
	WDT_ID_0,
	/// WDT ID 1
	WDT_ID_1,
} Wdt_Id;

/// List of UART ID
typedef enum {
	/// UART ID 0
	UART_ID_0,
	/// UART ID 1
	UART_ID_1,
	/// UART ID 2
	UART_ID_2,
	/// UART ID 3
	UART_ID_3,
	/// UART ID 4
	UART_ID_4,
} Uart_Id;

/// List of SPI ID
typedef enum {
	/// SPI ID 0
	SPI_ID_0,
	/// SPI ID 1
	SPI_ID_1,
	/// SPI ID 2
	SPI_ID_2,
	/// SPI ID 3
	SPI_ID_3,
} Spi_Id;

/// List of I2C ID
typedef enum {
	/// I2C ID 0
	I2C_ID_0,
	/// I2C ID 1
	I2C_ID_1,
} I2c_Id;

/// List of Common DMA Channel
typedef enum {
	DMA_CHAN_0,
	DMA_CHAN_1,
	DMA_CHAN_2,
	DMA_CHAN_3,
	DMA_CHAN_4,
	DMA_CHAN_5,
	DMA_CHAN_6,
	DMA_CHAN_7,

	DMA_CHAN_MAXIMUM,
} Dma_Chan;

/// List of Common DMA Channel
typedef enum {
	DMA_UART_DEV = 0,
	DMA_UART0_DEV = 0,
	DMA_UART1_DEV,
	DMA_UART2_DEV,
	DMA_UART3_DEV,
	DMA_UART4_DEV,
	DMA_I2C_DEV = 5,
	DMA_I2C0_DEV = 5,
	DMA_I2C1_DEV,
	DMA_SPI_DEV = 7,
	DMA_SPI0_DEV = 7,
	DMA_SPI1_DEV,
	DMA_SPI2_DEV,
	DMA_SPI3_DEV = 10,
	DMA_QSPI_DEV = 10,
} Dma_DevNum;


/// List of Security Operation
typedef enum {
	/// Software SHA256
	SEC_OP_SW_SHA256,
	/// Software AES encrypt
	SEC_OP_SW_AES_ENC,
	/// Software AES decrypt
	SEC_OP_SW_AES_DEC,
	/// Software SM4 encrypt
	SEC_OP_SW_SM4_ENC,
	/// Software SM4 decrypt
	SEC_OP_SW_SM4_DEC,

	/// Hardware SHA256
	SEC_OP_HW_SHA256,
	/// Hardware AES encrypt and use HW Key
	SEC_OP_HW_HK_AES_ENC,
	/// Hardware AES encrypt and use SW Key
	SEC_OP_HW_SK_AES_ENC,
	/// Hardware AES decrypt and use SW Key
	SEC_OP_HW_SK_AES_DEC,
	/// Hardware SM4 encrypt and use HW Key
	SEC_OP_HW_HK_SM4_ENC,
	/// Hardware SM4 encrypt and use SW Key
	SEC_OP_HW_SK_SM4_ENC,
	/// Hardware SM4 decrypt and use SW Key
	SEC_OP_HW_SK_SM4_DEC,
} Sec_Op_Code;

/// List of PMU PVD interrupt trigger voltage
typedef enum {
	PMU_PVD_LV_1_V_8,
	PMU_PVD_LV_1_V_9,
	PMU_PVD_LV_2_V_0,
	PMU_PVD_LV_2_V_1,
	PMU_PVD_LV_2_V_2,
	PMU_PVD_LV_2_V_3,
	PMU_PVD_LV_2_V_4,
	PMU_PVD_LV_2_V_5,
	PMU_PVD_LV_2_V_6,
	PMU_PVD_LV_2_V_7,
	PMU_PVD_LV_2_V_8,
	PMU_PVD_LV_2_V_9,
	PMU_PVD_LV_3_V_0,
	PMU_PVD_LV_3_V_1,
	PMU_PVD_LV_3_V_2,
	PMU_PVD_LV_3_V_3,
} Pmu_Pvd_Lv;

/// List of Monitor sample source
typedef enum {
	/// Monitor sample source
	MNT_SMP_SRC_MONITOR,
	/// HAC sample source
	MNT_SMP_SRC_HAC,
} Mnt_Smp_Src;

/// List of Monitor sample channel
typedef enum {
	MNT_ADC_SMP_CHANNEL_UA,
	MNT_ADC_SMP_CHANNEL_UB,
	MNT_ADC_SMP_CHANNEL_UC,
	MNT_ADC_SMP_CHANNEL_IA,
	MNT_ADC_SMP_CHANNEL_IB,
	MNT_ADC_SMP_CHANNEL_IC,
	MNT_ADC_SMP_CHANNEL_IN,
	MNT_ADC_SMP_CHANNEL_IL,
	MNT_ADC_SMP_CHANNEL_ARC_IA,
	MNT_ADC_SMP_CHANNEL_ARC_IB,
	MNT_ADC_SMP_CHANNEL_ARC_IC,
	MNT_ADC_SMP_CHANNEL_CD_IA,
	MNT_ADC_SMP_CHANNEL_CD_IB,
	MNT_ADC_SMP_CHANNEL_CD_IC,
}Mnt_Adc_Smp_Channel;

/// List of HAC sample channel
typedef enum {
	MNT_HAC_SMP_CHANNEL_UA,
	MNT_HAC_SMP_CHANNEL_UB,
	MNT_HAC_SMP_CHANNEL_UC,
	MNT_HAC_SMP_CHANNEL_IA,
	MNT_HAC_SMP_CHANNEL_IB,
	MNT_HAC_SMP_CHANNEL_IC,
	MNT_HAC_SMP_CHANNEL_IN,
	MNT_HAC_SMP_CHANNEL_FIL,
	MNT_HAC_SMP_CHANNEL_IT,
	MNT_HAC_SMP_CHANNEL_UT,
	MNT_HAC_SMP_CHANNEL_FUA,
	MNT_HAC_SMP_CHANNEL_FUB,
	MNT_HAC_SMP_CHANNEL_FUC,
	MNT_HAC_SMP_CHANNEL_FIA,
	MNT_HAC_SMP_CHANNEL_FIB,
	MNT_HAC_SMP_CHANNEL_FIC,
	MNT_HAC_SMP_CHANNEL_FIN,
	MNT_HAC_SMP_CHANNEL_FIT,
}Mnt_Hac_Smp_Channel;

/// List of Zero-Crossing interrputs
typedef enum {
	MNT_ZCP_INT_UA,
	MNT_ZCP_INT_UB,
	MNT_ZCP_INT_UC,
	MNT_ZCP_INT_IA,
	MNT_ZCP_INT_IB,
	MNT_ZCP_INT_IC,
	MNT_ZCP_INT_IN,
	MNT_ZCP_INT_IL,
	MNT_ZCP_INT_IT,
	MNT_ZCN_INT_UA,
	MNT_ZCN_INT_UB,
	MNT_ZCN_INT_UC,
	MNT_ZCN_INT_IA,
	MNT_ZCN_INT_IB,
	MNT_ZCN_INT_IC,
	MNT_ZCN_INT_IN,
	MNT_ZCN_INT_IL,
	MNT_ZCN_INT_IT,
} Mnt_Zcp_Int;

/// List of ARC-Detection interrputs
typedef enum {
	MNT_ARC_INT_IA,
	MNT_ARC_INT_IB,
	MNT_ARC_INT_IC,
} Mnt_Arc_Int;

/// List of Abnormal-Triggered interrputs
typedef enum {
	MNT_ABN_INT_SAG_UC,
	MNT_ABN_INT_SAG_UB,
	MNT_ABN_INT_SAG_UA,
	MNT_ABN_INT_OVP_UC,
	MNT_ABN_INT_OVP_UB,
	MNT_ABN_INT_OVP_UA,
	MNT_ABN_INT_LOSV_UC,
	MNT_ABN_INT_LOSV_UB,
	MNT_ABN_INT_LOSV_UA,
	MNT_ABN_INT_SC_IC,
	MNT_ABN_INT_SC_IB,
	MNT_ABN_INT_SC_IA,
	MNT_ABN_INT_OVF_ILRMS,
	MNT_ABN_INT_OVF_IC,
	MNT_ABN_INT_OVF_IB,
	MNT_ABN_INT_OVF_IA,
	MNT_ABN_INT_UPHSQ_ERR,
	MNT_ABN_INT_ZC_OT,
} Mnt_Abn_Int;

/// List of ARC-Detection data source
typedef enum {
	MNT_ARC_SAR_ADC_MUX,
	MNT_ARC_SD_ADC_MUX,
} Mnt_Arc_Adc_Mux;

/// List of ARC-Detection Wavlet enable mode
typedef enum {
	MNT_ARC_WAVLET_Y1_N23,
	MNT_ARC_WAVLET_Y1N23,
	MNT_ARC_WAVLET_Y12_N3,
	MNT_ARC_WAVLET_Y123,
}Mnt_Arc_Wavlet_En;

/// List of ARC-Detection HPF Para
typedef enum {
	MNT_ARC_HIGH_B0,
	MNT_ARC_HIGH_B1,
	MNT_ARC_HIGH_B2,
	MNT_ARC_HIGH_B3,
	MNT_ARC_HIGH_B4,
	MNT_ARC_HIGH_B5,
	MNT_ARC_HIGH_B6,
	MNT_ARC_HIGH_B7,
}Mnt_Arc_High_Bx;

/// List of ARC-Detection LPF Para
typedef enum {
	MNT_ARC_LOW_B0,
	MNT_ARC_LOW_B1,
	MNT_ARC_LOW_B2,
	MNT_ARC_LOW_B3,
	MNT_ARC_LOW_B4,
	MNT_ARC_LOW_B5,
	MNT_ARC_LOW_B6,
	MNT_ARC_LOW_B7,
}Mnt_Arc_Low_Bx;

/// List of ARC-Detection data source to be analyzed
typedef enum {
	MNT_ARC_DEC_SOUR_CD1_SEL,
	MNT_ARC_DEC_SOUR_CD2_SEL,
	MNT_ARC_DEC_SOUR_CD3_SEL,
}Mnt_Arc_Dec_Sour_Sel;

/// ARC-Detection Function Enable/Disable
typedef enum {
	MNT_ARC_DIS,
	MNT_ARC_EN,
} Mnt_Arc_Enable;

/*
 * TYPE DEFINITIONS
 ****************************************************************************************
 */
typedef struct spi_cfg Spi_Cfg_t, *Spi_Cfg_t_Ptr;

/// SPI configuration structure
struct spi_cfg {
	/// SPI Device ID
	Spi_Id devid;
	/// SPI slave select
	uint8_t spi_cs;
};

/// Arc-detection basic configuration structure
typedef struct {
	Mnt_Arc_Adc_Mux mux;
	Mnt_Arc_Wavlet_En wav_en;
} Mnt_Arc_Basic_Para_t;

/// Arc-detection HPF/LPF configuration structure
typedef struct {
	Mnt_Arc_High_Bx high_bx;
	int16_t high_val;
	Mnt_Arc_Low_Bx low_bx;
	int16_t low_val;
} Mnt_Arc_Filter_Para_t;

/// Arc-detection error check configuration structure
typedef struct {
	Mnt_Arc_Dec_Sour_Sel dec_sour_sel;
	uint16_t half_wave_num;
	Mnt_Arc_Enable en_peak;
	Mnt_Arc_Enable en_average;
	uint8_t par_val;
	uint8_t max_bit;
} Mnt_Arc_Err_Check_Para_t;

/// @} HAL_API

/**
 ****************************************************************************************
 * @addtogroup HAL_CALLBACK HAL Callback Functions
 * @ingroup HAL_API
 * @brief Description of HAL Callback Functions
 * @{
 ****************************************************************************************
 */

/*
 * CALLBACK FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Interrupt Callback function
 *
 * @param[in] ptr       Pointer to the param of interrupt Callback function
 *
 * @return None
 ****************************************************************************************
 */
typedef void (*Hal_Irq_Callback)(void *ptr);

/**
 ****************************************************************************************
 * @brief RTC Callback function
 *
 * @param[in] ptr       Pointer to the param of RTC Callback function
 *
 * @return None
 ****************************************************************************************
 */
typedef void (*Hal_Rtc_Callback)(void *ptr);

/**
 ****************************************************************************************
 * @brief WDT Callback function
 *
 * @param[in] ptr       Pointer to the param of WDT Callback function
 *
 * @return None
 ****************************************************************************************
 */
typedef void (*Hal_Wdt_Callback)(void *ptr);

/**
 ****************************************************************************************
 * @brief TIMER Callback function
 *
 * @param[in] ptr       Pointer to the param of TIMER Callback function
 *
 * @return None
 ****************************************************************************************
 */
typedef void (*Hal_Timer_Callback)(void *ptr);

/**
 ****************************************************************************************
 * @brief DMA Callback function
 *
 * @param[in] chan       DMA Channel ID
 * @param[in] status     DMA Channel Execution Status
 *
 * @return None
 ****************************************************************************************
 */
typedef void (*Hal_Dma_Callback)(dma_chan_t chan, uint32_t status);

/**
 ****************************************************************************************
 * @brief PMU PVD Interrupt Callback function
 *
 * @param[in] ptr       Pointer to the param of PMU Callback function
 *
 * @return None
 ****************************************************************************************
 */
typedef void (*Hal_Pmu_Callback)(void *ptr);

/**
 ****************************************************************************************
 * @brief SARADC temp warning int Callback function
 *
 * @return None
 ****************************************************************************************
 */
typedef void (*Hal_Saradc_Callback)(void);

/**
 ****************************************************************************************
 * @brief Monitor Interrupt Callback function
 *
 * @param[in] ptr       Pointer to the param of Monitor Callback function
 *
 * @return None
 ****************************************************************************************
 */
typedef void (*Hal_Mnt_Callback)(void *ptr);

/// @} HAL_CALLBACK

/**
 ****************************************************************************************
 * @addtogroup HAL_PCL_API HAL PCL APIs
 * @ingroup HAL_API
 * @brief Description of HAL PCL APIs
 * @{
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Set PCL PIN function
 *
 * @param[in] id          PIN ID
 * @param[in] func        PIN function (see #Pcl_Pin_Func enumeration)
 *
 * @return Function execution result
 *
 ****************************************************************************************
 */
int32_t Hal_Pcl_FuncSet(Pad_Id_t id, Pcl_Pin_Func func);

/**
 ****************************************************************************************
 * @brief Get PCL PIN function
 *
 * @param[in] id          PIN ID
 *
 * @return PIN function (see #Pcl_Pin_Func enumeration)
 *
 ****************************************************************************************
 */
Pcl_Pin_Func Hal_Pcl_FuncGet(Pad_Id_t id);

/**
 ****************************************************************************************
 * @brief Configure PCL PIN Pull-Up or Pull-Down enable/disable
 *
 * @param[in] id          PIN ID
 * @param[in] cfg         Pull-Up or Pull-Down enable/disable
 *
 * @return None
 *
 ****************************************************************************************
 */
void Hal_Pcl_PdPuSet(Pad_Id_t id, Pcl_Pd_Pu_Set cfg);

/**
 ****************************************************************************************
 * @brief Configure PCL PIN Output enable/disable
 *
 * @param[in] id          PIN ID
 * @param[in] cfg         PIN Output enable/disable
 *
 * @return None
 *
 ****************************************************************************************
 */
void Hal_Pcl_OutputSet(Pad_Id_t id, Pcl_Output_Set cfg);

/// @} HAL_PCL_API

/**
 ****************************************************************************************
 * @addtogroup HAL_GPIO_API HAL GPIO APIs
 * @ingroup HAL_API
 * @brief Description of HAL GPIO APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Read GPIO pin value
 *
 * @param[in] port          GPIO port ID (see #Gpio_Port enumeration)
 * @param[in] pin           GPIO pin ID (see #Gpio_Pin enumeration)
 *
 * @return <0 ERROR_CODE, >=0 GPIO pin value
 ****************************************************************************************
 */
int32_t Hal_Gpio_GetVal(Gpio_Port port, Gpio_Pin pin);

/**
 ****************************************************************************************
 * @brief Write GPIO pin value
 *
 * @param[in] port          GPIO port ID (see #Gpio_Port enumeration)
 * @param[in] pin           GPIO pin ID (see #Gpio_Pin enumeration)
 * @param[in] val           GPIO pin value (see #Gpio_Pin_Val enumeration)
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Gpio_SetVal(Gpio_Port port, Gpio_Pin pin, Gpio_Pin_Val val);


/**
 ****************************************************************************************
 * @brief Enable GPIO pin intterupt
 *
 * @param[in] port          GPIO port ID (see #Gpio_Port enumeration)
 * @param[in] pin           GPIO pin ID (see #Gpio_Pin enumeration)
 * @param[in] cfg_pararm    GPIO pin int config (see #DEV_GPIO_INT_CFG)
 * @param[in] isr_param     GPIO pin int handler (see #DEV_GPIO_BIT_ISR)
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Gpio_Int_Enable(Gpio_Port port, Gpio_Pin pin, DEV_GPIO_INT_CFG_PTR cfg_param, DEV_GPIO_BIT_ISR_PTR isr_param);


/**
 ****************************************************************************************
 * @brief Enable GPIO pin intterupt
 *
 * @param[in] port          GPIO port ID (see #Gpio_Port enumeration)
 * @param[in] pin           GPIO pin ID (see #Gpio_Pin enumeration)
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Gpio_Int_Disable(Gpio_Port port, Gpio_Pin pin);


/// @} HAL_GPIO_API

/**
 ****************************************************************************************
 * @addtogroup HAL_UART_API HAL UART APIs
 * @ingroup HAL_API
 * @brief Description of HAL UART APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Set UART baudrate
 *
 * @param[in] uart          UART Device ID
 * @param[in] baudrate      UART Baudrate
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Uart_SetBaud(Uart_Id uart, uint32_t baudrate);

void Hal_Console_PutChar(char c);

/**
 ****************************************************************************************
 * @brief UART Output char
 *
 * @param[in] uart          UART Device ID
 * @param[in] c             Output char
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Uart_PutChar(Uart_Id uart, char c);

char Hal_Console_GetChar(void);

/**
 ****************************************************************************************
 * @brief GET UART Input char
 *
 * @param[in] uart           UART Device ID
 *
 * @return Input char
 ****************************************************************************************
 */
char Hal_Uart_GetChar(Uart_Id uart);

void Hal_Console_PutStr(const char *str, uint32_t len);

/**
 ****************************************************************************************
 * @brief UART Output String
 *
 * @param[in] uart          UART Device ID
 * @param[in] str           Output String
 * @param[in] len           Output String Length
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Uart_PutStr(Uart_Id uart, const char *str, uint32_t len);

void Hal_Console_GetStr(char *str, uint32_t len);

/**
 ****************************************************************************************
 * @brief GET UART input String
 *
 * @param[in] uart          UART Device ID
 * @param[output] str       Pointer to input String
 * @param[output] len       Input String Length
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Uart_GetStr(Uart_Id uart, char *str, uint32_t len);

/**
 ****************************************************************************************
 * @brief Uart Dma Send
 *
 * @param[in] uart          UART Device ID
 * @param[output] w_buf     Pointer to wirte buf
 * @param[output] len       Send Length
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Uart_Dma_Write(Uart_Id uart, uint8_t *w_buf, uint32_t w_len);

/**
 ****************************************************************************************
 * @brief Uart Dma Receive
 *
 * @param[in] uart          UART Device ID
 * @param[in] r_buf     Pointer to read buf
 * @param[in] len       Receive Length
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Uart_Dma_Read(Uart_Id uart, uint8_t *r_buf, uint32_t r_len);

/**
 ****************************************************************************************
 * @brief Uart Request Dma Channel
 *
 * @param[in] uart          UART Device ID
 * @param[in] tx_chan       Dma Tx Channel
 * @param[in] rx_chan       Dma Rx Channel
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Uart_Request_Dma_Chan(Uart_Id uart, uint8_t tx_chan, uint8_t rx_chan);
/// @} HAL_UART_API

/**
 ****************************************************************************************
 * @addtogroup HAL_SYSCNT_API HAL SYSCNT APIs
 * @ingroup HAL_API
 * @brief Description of HAL SYSCNT APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Get timestamp
 *
 * @return timestamp (Unit: microseconds)
 ****************************************************************************************
 */
Sys_Timestamp_t Hal_Cnt_GetTimestamp(void);

/**
 ****************************************************************************************
 * @brief SYSCNT microseconds delay in cycle
 *
 * @param[in] usec           microseconds
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Cnt_DelayUs(uint32_t usec);

/**
 ****************************************************************************************
 * @brief SYSCNT milliseconds delay in cycle
 *
 * @param[in] msec           milliseconds
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Cnt_DelayMs(uint32_t msec);

/// @} HAL_SYSCNT_API

/**
 ****************************************************************************************
 * @addtogroup HAL_TIMER_API HAL TIMER APIs
 * @ingroup HAL_API
 * @brief Description of HAL TIMER APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Start a ontshot timer
 *
 * @param[in] timer            Timer Device ID
 * @param[in] ms               Timer timeout(Unit: milliseconds)
 * @param[in] cb               Timer interrupt callback function
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Timer_StartOneshot(Timer_Id timer, uint32_t ms, Hal_Timer_Callback cb);

/**
 ****************************************************************************************
 * @brief Start a period timer
 *
 * @param[in] timer            Timer Device ID
 * @param[in] us               Timer timeout(Unit: microseconds)
 * @param[in] cb               Timer interrupt callback function
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Timer_StartPeriod(Timer_Id timer, uint32_t us, Hal_Timer_Callback cb);

/**
 ****************************************************************************************
 * @brief Stop period timer
 *
 * @param[in] timer            Timer Device ID
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Timer_StopPeriod(Timer_Id timer);

/// @} HAL_TIMER_API

/**
 ****************************************************************************************
 * @addtogroup HAL_RTC_API HAL RTC APIs
 * @ingroup HAL_API
 * @brief Description of HAL RTC APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Get RTC Datetime
 *
 * @param[out] tm           RTC Datetime
 *
 * @return Function execution result
 ****************************************************************************************
 */
void Hal_Rtc_SetDatetime(Datetime_t_Ptr tm);
int32_t Hal_Rtc_GetDatetime(Datetime_t_Ptr tm);

/**
 ****************************************************************************************
 * @brief RTC Start
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Rtc_Start(void);

/**
 ****************************************************************************************
 * @brief RTC Stop
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Rtc_Stop(void);

/**
 ****************************************************************************************
 * @brief RTC Set Alarm
 *
 * @param[in] sec         Alarm timeout(Unit:Seconds)
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Rtc_SetAlarm(uint32_t sec);

/**
 ****************************************************************************************
 * @brief Regist timer interrupt callback function
 *
 * @param[in] cb               Timer interrupt callback function
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Rtc_RegisterCb(Hal_Rtc_Callback cb);

/// @} HAL_RTC_API

/**
 ****************************************************************************************
 * @addtogroup HAL_PWM_API HAL PWM APIs
 * @ingroup HAL_API
 * @brief Description of HAL PWM APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Start a PWM output
 *
 * @param[in] pwm                PWM ID to Start
 * @param[in] duty_cycle         Duty Cycle of PWM Output signal
 * @param[in] duty_cycle         Frequency of PWM Output signal
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Pwm_Start(Pwm_Id pwm, uint32_t duty_cycle, uint32_t hz);

/**
 ****************************************************************************************
 * @brief Start the PWM output
 *
 * @param[in] pwm                PWM ID to Stop
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Pwm_Stop(Pwm_Id pwm);

/// @} HAL_PWM_API

/**
 ****************************************************************************************
 * @addtogroup HAL_FLASH_API HAL FLASH APIs
 * @ingroup HAL_API
 * @brief Description of HAL FLASH APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief SPI Flash Write
 *
 * @param[in] addr            SPI Flash address to write
 * @param[in] size            Data size to write
 * @param[in] data            Data to write
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Flash_Write(Flash_Addr_t addr, uint32_t size, const uint8_t *data);

/**
 ****************************************************************************************
 * @brief SPI Flash Read
 *
 * @param[in] addr            SPI Flash address to read
 * @param[in] size            Data size to read
 * @param[output] data        Data to read
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Flash_Read(Flash_Addr_t addr, uint32_t size, uint8_t *data);

/**
 ****************************************************************************************
 * @brief SPI Flash Erase
 *
 * @param[in] addr            SPI Flash address to erase
 * @param[in] size            Data size to erase
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Flash_Erase(Flash_Addr_t addr, uint32_t size);

/**
 ****************************************************************************************
 * @brief SPI Flash Erase All
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Flash_ChipErase(void);

/**
 ****************************************************************************************
 * @brief SPI Flash Erase and Write
 *
 * @param[in] addr            SPI Flash address to erase and write
 * @param[in] size            Data size to erase and write
 * @param[in] data            Data to write
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Flash_EraseWrite(Flash_Addr_t addr, uint32_t size, const uint8_t *data);

/**
 ****************************************************************************************
 * @brief Enable Flash XIP
 *
 * @return None
 ****************************************************************************************
 */
//void Hal_Flash_XipEn(void);

/**
 ****************************************************************************************
 * @brief Disable Flash XIP
 *
 * @return None
 ****************************************************************************************
 */
//void Hal_Flash_XipDis(void);

/// @} HAL_FLASH_API

/**
 ****************************************************************************************
 * @addtogroup HAL_SPI_API HAL SPI APIs
 * @ingroup HAL_API
 * @brief Description of HAL SPI APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief SPI write read data
 *
 * @param[in] ptr               SPI user configration
 * @param[in] inst              SPI Slave device Instruction
 * @param[in] addr              SPI Slave device address
 * @param[in] w_buf             Buffer to be written
 * @param[in] w_size            Size of write buffer
 * @param[in] r_buf             Buffer to be read
 * @param[in] r_size            Size of read buffer
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_Spi_Transfer(Spi_Cfg_t_Ptr ptr, uint8_t *w_buf, uint32_t w_len,
			uint8_t *r_buf, uint32_t r_len);

/**
 ****************************************************************************************
 * @brief SPI Request Dma Channel
 *
 * @param[in] ptr               SPI user configration
 * @param[in] tx_chan           Dma tx channel
 * @param[in] rx_chan           Dma rx channel
 *
 * @return Function execution result
 ****************************************************************************************
*/
int32_t Hal_Spi_Request_Dma_Chan(Spi_Cfg_t_Ptr ptr, uint8_t tx_chan, uint8_t rx_chan);

/// @} HAL_SPI_API

/**
 ****************************************************************************************
 * @addtogroup HAL_I2C_API HAL I2C APIs
 * @ingroup HAL_API
 * @brief Description of HAL I2C APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief I2C data Read
 *
 * @param[in] i2c                  I2C Device ID
 * @param[out] r_buf               Buffer for read data
 * @param[in] r_size               Size of data to be read
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_I2c_Read(I2c_Id i2c, uint8_t *r_buf, uint32_t r_size);

/**
 ****************************************************************************************
 * @brief I2C data Write
 *
 * @param[in] i2c                  I2C Device ID
 * @param[in] w_buf                Buffer to be written
 * @param[in] w_size               Size of write buffer
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_I2c_Write(I2c_Id i2c, uint8_t *w_buf, uint32_t w_size);

/**
 ****************************************************************************************
 * @brief I2C config target addr
 *
 * @param[in] i2c                  I2C Device ID
 * @param[in] tar_addr             I2C Slave target address
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_I2c_Tar_Add_Cfg(I2c_Id i2c, uint32_t tar_addr);

/**
 ****************************************************************************************
 * @brief I2C request dma channel
 *
 * @param[in] i2c                  I2C Device ID
 * @param[in] tx_chan              I2C tx dma channel
 * @param[in] rx_chan              I2C rx dma channel
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_I2c_Request_Dma_Chan(I2c_Id i2c, uint8_t tx_chan, uint8_t rx_chan);

/**
 ****************************************************************************************
 * @brief I2C dma write
 *
 * @param[in] i2c                  I2C Device ID
 * @param[in] w_buf                write data buf contain i2c cmd
 * @param[in] w_len                write data len
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_I2c_Dma_Write(I2c_Id i2c, uint16_t *w_buf, uint32_t w_len);

/**
 ****************************************************************************************
 * @brief I2C dma write
 *
 * @param[in] i2c                  I2C Device ID
 * @param[in] w_buf                i2c cmd buf
 * @param[in] w_len                write data len
 * @param[in] r_buf                i2c read data buf
 * @param[in] r_len                read data len
 *
 * @return Function execution result
 ****************************************************************************************
 */
int32_t Hal_I2c_Dma_Read(I2c_Id i2c, uint16_t *w_buf, uint32_t w_len, uint32_t *r_buf, uint32_t r_len);

/// @} HAL_I2C_API

/**
 ****************************************************************************************
 * @addtogroup HAL_WDT_API HAL WDT APIs
 * @ingroup HAL_API
 * @brief Description of HAL WDT APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Start a watchdog
 *
 * @param[in] wdt          Watchdog device ID
 * @param[in] timeout      Watchdog timeout value
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Wdt_Start(Wdt_Id wdt, uint32_t timeout);

/**
 ****************************************************************************************
 * @brief Stop a watchdog
 *
 * @param[in] wdt          Watchdog device ID
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Wdt_Stop(Wdt_Id wdt);

/**
 ****************************************************************************************
 * @brief Feed a watchdog
 *
 * @param[in] wdt          Watchdog device ID
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Wdt_Kick(Wdt_Id wdt);

/**
 ****************************************************************************************
 * @brief Get watchdog timeout value
 *
 * @param[in] wdt          Watchdog device ID
 *
 * @return Watchdog timeout value
 ****************************************************************************************
 */
uint32_t Hal_Wdt_GetTimeout(Wdt_Id wdt);

/**
 ****************************************************************************************
 * @brief Get watchdog time left
 *
 * @param[in] wdt          Watchdog device ID
 *
 * @return watchdog time left
 ****************************************************************************************
 */
uint32_t Hal_Wdt_GetTimeleft(Wdt_Id wdt);

/**
 ****************************************************************************************
 * @brief Watchdog interrupt callback register
 *
 * @param[in] cb           Watchdog interrupt callback function
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Wdt_RegisterCb(Hal_Wdt_Callback cb);

/// @} HAL_WDT_API

/**
 ****************************************************************************************
 * @addtogroup HAL_INTC_API HAL INTC APIs
 * @ingroup HAL_API
 * @brief Description of HAL INTC APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Register the interrupt
 *
 * @param[in] nr            Interrupt ID
 * @param[in] cb            Interrupt handler function
 * @param[in] priv          Pointer to interrupt handler private data
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Irq_Register(Irq_Num_t nr, Hal_Irq_Callback cb, void *priv);

/**
 ****************************************************************************************
 * @brief Enable Interrupt
 *
 * @param[in] nr            Interrupt ID
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Irq_Enable(Irq_Num_t nr);

/**
 ****************************************************************************************
 * @brief Disable Interrupt
 *
 * @param[in] nr            Interrupt ID
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Irq_Disable(Irq_Num_t nr);

/**
 ****************************************************************************************
 * @brief Interrupt Priority configure
 *
 * @param[in] nr            Interrupt ID
 * @param[in] priority      Interrupt priority
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Irq_SetPriority(Irq_Num_t nr, uint32_t priority);

/// @} HAL_INTC_API


/**
 ****************************************************************************************
 * @addtogroup HAL_DMA_API HAL DMA APIs
 * @ingroup HAL_API
 * @brief Description of HAL DMA APIs
 * @{
 ****************************************************************************************
 */
/**
 ****************************************************************************************
 * @brief Allocate DMA channel
 *
 * @param[in] chan           Channel ID
 *
 * @return Execution status
 ****************************************************************************************
 */
int32_t Hal_Dma_Alloc_Chan(dma_chan_t chan);

/**
 ****************************************************************************************
 * @brief Allocate DMA channel
 *
 * @param[in] chan           Channel ID
 * @param[in] sAddr          Source Address
 * @param[in] dAddr          Destination Address
 * @param[in] xfer_len       Transfer Length
 * @param[in] dir            Transfer Direction
 * @param[in] rBurst         Read Burst Size
 * @param[in] wBurst         Write Burst Size
 * @param[in] tx             TX Ack Bytes
 * @param[in] rx             RX Ack Bytes
 * @param[in] id             Peripheral DRQ Line
 * @param[in] pri            Channel Priority
 *
 * @return Execution status
 ****************************************************************************************
 */
int32_t Hal_Dma_Config(dma_chan_t chan, dma_addr_t sAddr, dma_addr_t dAddr, uint32_t xfer_len,
		       dma_dir_t dir, dma_burst_size_t rBurst, dma_burst_size_t wBurst, dma_ack_bytes_t tx,
		       dma_ack_bytes_t rx, dma_slave_id_t id, dma_priority_t pri);

/**
 ****************************************************************************************
 * @brief Invalidate the data length by address
 *
 * @param[in] chan           Address
 * @param[in] cb             Data length
 *
 * @return none
 ****************************************************************************************
 */
void Hal_Dma_Data_Invalidate(dma_addr_t addr, uint32_t len);
/**
 ****************************************************************************************
 * @brief Register DMA channel interrupt
 *
 * @param[in] chan           Channel ID
 * @param[in] cb             Channel Process Callback
 *
 * @return none
 ****************************************************************************************
 */
void Hal_Dma_Register_Callback(dma_chan_t chan, Hal_Dma_Callback cb);

/**
 ****************************************************************************************
 * @brief Start DMA Transfer
 *
 * @param[in] chan           Channel ID
 *
 * @return none
 ****************************************************************************************
 */
void Hal_Dma_Xfer_Start(dma_chan_t chan);

/**
 ****************************************************************************************
 * @brief Prepare DMA Transfer
 *
 * @param[in] chan           Channel ID
 *
 * @return none
 ****************************************************************************************
 */
void Hal_Dma_Xfer_Pending(dma_chan_t chan);

/**
 ****************************************************************************************
 * @brief Start Multiple DMA Channels Transfer
 *
 * @param[in] chan           Channel Mask
 *
 * @return none
 ****************************************************************************************
 */
void Hal_Dma_Xfer_Multichan_Start(dma_chan_mask_t mask);

/**
 ****************************************************************************************
 * @brief Abort DMA Transfer
 *
 * @param[in] chan           Channel ID
 *
 * @return none
 ****************************************************************************************
 */
void Hal_Dma_Xfer_Abort(dma_chan_t chan);

/**
 ****************************************************************************************
 * @brief Suspend DMA Channel
 *
 * @param[in] chan           Channel ID
 *
 * @return none
 ****************************************************************************************
 */
void Hal_Dma_Xfer_Suspend(dma_chan_t chan);

/**
 ****************************************************************************************
 * @brief Unsuspend DMA Channel
 *
 * @param[in] chan           Channel ID
 *
 * @return none
 ****************************************************************************************
 */
void Hal_Dma_Xfer_Unsuspend(dma_chan_t chan);

/**
 ****************************************************************************************
 * @brief Free DMA Channel
 *
 * @param[in] chan           Channel ID
 *
 * @return Execution Status
 ****************************************************************************************
 */
int32_t Hal_Dma_Free_Chan(dma_chan_t chan);

/**
 ****************************************************************************************
 * @brief Print DMA Channel Transfer Rate
 *
 * @param[in] chan           Channel ID
 *
 * @return none
 ****************************************************************************************
 */
void Hal_Dma_Print_Chan_Rate(dma_chan_t chan);

/// @} HAL_DMA_API

/**
 ****************************************************************************************
 * @addtogroup HAL_SEC_API HAL SEC APIs
 * @ingroup HAL_API
 * @brief Description of HAL SEC APIs
 * @{
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Calculate hash value by SHA256
 *
 * @param[in] input           Data Used to calculate hash
 * @param[in] len             Input Data length
 * @param[out] hash           Hash result to return
 * @param[in] op              Sw/Hw SHA256 Opcode
 *
 * @return Execution status
 ****************************************************************************************
 */
int32_t Hal_Sec_Sha256(uint8_t *input, uint32_t len, uint8_t *hash, Sec_Op_Code op);

/**
 ****************************************************************************************
 * @brief Software AES/SM4 Encrypt/Decrypt
 *
 * @param[in] input           Sw AES/SM4 Encrypt/Decrypt input data buffer
 * @param[in] len             Input Data length
 * @param[out] output         Sw AES/SM4 Encrypt/Decrypt output data buffer
 * @param[in] key             Sw Encrypt/Decrypt key
 * @param[in] key_len         Sw Encrypt/Decrypt key length
 * @param[in] op              Sw AES/SM4 Encrypt/Decrypt Opcode
 *
 * @return Execution status
 ****************************************************************************************
 */
int32_t Hal_Sec_Sw_Crypto(uint8_t *input, uint32_t len, uint8_t *output,
				uint8_t *key, uint32_t key_len, Sec_Op_Code op);

/**
 ****************************************************************************************
 * @brief Hardware AES/SM4 Encrypt used hardware key
 *
 * @param[in] input           Hw AES/SM4 Encrypt input data buffer
 * @param[in] len             Input Data length
 * @param[out] key_out        Hw AES/SM4 Encrypt Key to return
 * @param[out] output         Hw AES/SM4 Encrypt output data buffer
 * @param[in] seed            Random number seed used to generate hardware key 
 * @param[in] op              Hw AES/SM4 Encrypt used hardware key Opcode
 *
 * @return Execution status
 ****************************************************************************************
 */
int32_t Hal_Sec_Hw_Hk_Crypto(uint8_t *input, uint32_t len, uint8_t *key_out,
				uint8_t *output, int seed, Sec_Op_Code op);

/**
 ****************************************************************************************
 * @brief Hardware AES/SM4 Encrypt/Decrypt used software key
 *
 * @param[in] input           Hw AES/SM4 Encrypt/Decrypt input data buffer
 * @param[in] len             Input Data length
 * @param[in] key             Hw AES/SM4 Encrypt/Decrypt Key
 * @param[in] key_len         Hw Encrypt/Decrypt key length
 * @param[out] output         Hw AES/SM4 Encrypt/Decrypt output data buffer
 * @param[in] op              Hw AES/SM4 Encrypt/Decrypt used software key Opcode
 *
 * @return Execution status
 ****************************************************************************************
 */
int32_t Hal_Sec_Hw_Sk_Crypto(uint8_t *input, uint32_t len, uint8_t *key,
				uint32_t key_len, uint8_t *output, Sec_Op_Code op);

/// @} HAL_SEC_API

/**
 ****************************************************************************************
 * @addtogroup HAL_EFUSE_API HAL EFUSE APIs
 * @ingroup HAL_API
 * @brief Description of HAL EFUSE APIs
 * @{
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Read efuse data
 *
 * @param[in] addr           Read address
 * @param[out] data          Read data buffer
 * @param[in] len            Data length
 *
 * @return Execution status
 ****************************************************************************************
 */
int32_t Hal_Efuse_Read(uint32_t addr, uint8_t *data, uint32_t len);

/**
 ****************************************************************************************
 * @brief Write efuse
 *
 * @param[in] addr           Write address
 * @param[in] data           Write data buffer
 * @param[in] len            Data length
 *
 * @return Execution status
 ****************************************************************************************
 */
int32_t Hal_Efuse_Write(uint32_t addr, uint8_t *data, uint32_t len);

/// @} HAL_EFUSE_API

/**
 ****************************************************************************************
 * @addtogroup HAL_PMU_API HAL PMU APIs
 * @ingroup HAL_API
 * @brief Description of HAL PMU APIs
 * @{
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief PMU PVD interrupt callback register
 *
 * @param[in] pwron_cb           PMU PVD rise interrupt callback function
 * @param[in] pwroff_cb          PMU PVD fall interrupt callback function
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Pmu_RegisterCb(Hal_Pmu_Callback pwron_cb, Hal_Pmu_Callback pwroff_cb);

/**
 ****************************************************************************************
 * @brief Enter Battery Mode
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Pmu_Enter_Bat_Mode(void);

/**
 ****************************************************************************************
 * @brief Configure the voltage threshold for triggering PVD interrupt
 *
 * @param[in] lv           Voltage threshold (see #Pmu_Pvd_Lv enumeration)
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Pmu_Cfg_Pvd_Lv(Pmu_Pvd_Lv lv);

/// @} HAL_PMU_API

/**
 ****************************************************************************************
 * @addtogroup HAL_ISP_API HAL ISP APIs
 * @ingroup HAL_API
 * @brief Description of HAL ISP APIs
 * @{
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Start ISP Program
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Isp_Start(void);

/// @} HAL_ISP_API

 /**
 ****************************************************************************************
 * @addtogroup HAL_SARADC_API HAL SARADC APIs
 * @ingroup HAL_API
 * @brief Description of HAL SARADC APIs
 * @{
*****************************************************************************************
*/

 /**
  ****************************************************************************************
 * @brief saradc enable or disable
 *
 * @param[in] enable           saradc enable flag
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Saradc_Enable(bool enable);

/**
 ****************************************************************************************
 * @brief saradc temp warning threshold value cfg
 *
 * @param[in] value            temp warning threshold
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Saradc_temp_threshold_cfg(uint32_t value);

/**
 ****************************************************************************************
 * @brief saradc temp warning int callback register
 *
 * @param[in] cb            temp warning int callback
 *
 * @return None
 ****************************************************************************************
 */

void Hal_Saradc_register_int_callback(Hal_Saradc_Callback cb);

/// @} HAL_SARADC_API

/**
 ****************************************************************************************
 * @addtogroup HAL_MNT_API HAL MNT APIs
 * @ingroup HAL_API
 * @brief Description of HAL MNT APIs
 * @{
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Configure Monitor Sample Parameter
 *
 * @param[in] smp_buf_size      Sample buffer size for all channel
 * @param[in] smp_src           Sample data source (see #Mnt_Smp_Src enumeration)
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_Configure(uint32_t smp_buf_size, Mnt_Smp_Src smp_src);

/**
 ****************************************************************************************
 * @brief Start single sample
 *
 * @param[in] ch_list      Sample channel list
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_SingleSmp_Start(uint32_t ch_list);

/**
 ****************************************************************************************
 * @brief Start continuous sample
 *
 * @param[in] ch_list      Sample channel list
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_ContSmp_Start(uint32_t ch_list);

/**
 ****************************************************************************************
 * @brief Stop continuous sample
 *
 * @param[in] ch_list      Sample channel list
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_ContSmp_Stop(uint32_t ch_list);

/**
 ****************************************************************************************
 * @brief Start non-arc zero-crossing sample
 *
 * @param[in] ch_list      Sample channel list
 * @param[in] smp_num      Sample number
 * @param[in] zcp_int      Zero-Crossing interrupt as non-arc sample triggered for each channel
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_ZcpSmp_Start(uint32_t ch_list, uint32_t smp_num, uint8_t *zcp_int);

/**
 ****************************************************************************************
 * @brief Start arc zero-crossing sample
 *
 * @param[in] ch_list      Sample channel list
 * @param[in] smp_num      Sample number
 * @param[in] zcp_arc_int  Zero-Crossing interrupt as arc sample triggered for each channel
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_ZcpArcSmp_Start(uint32_t ch_list, uint32_t smp_num, uint8_t *zcp_arc_int);

/**
 ****************************************************************************************
 * @brief Stop zero-crossing sample
 *
 * @param[in] ch_list      Sample channel list
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_ZcpSmp_Stop(uint32_t ch_list);

/**
 ****************************************************************************************
 * @brief Start non-arc abnornal sample
 *
 * @param[in] ch_list      Sample channel list
 * @param[in] smp_num      Sample number
 * @param[in] abn_int      Abnornal interrupt as non-arc sample triggered for each channel
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_AbnSmp_Start(uint32_t ch_list, uint32_t smp_num, uint8_t *abn_int);

/**
 ****************************************************************************************
 * @brief Start arc abnornal sample
 *
 * @param[in] ch_list      Sample channel list
 * @param[in] smp_num      Sample number
 * @param[in] abn_arc_int  Abnornal interrupt as arc sample triggered for each channel
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_AbnArcSmp_Start(uint32_t ch_list, uint32_t smp_num, uint8_t *abn_arc_int);

/**
 ****************************************************************************************
 * @brief Configure arc-detection parameter
 *
 * @param[in] basic      Pointer to arc basic parameter (see #Mnt_Arc_Basic_Para_t enumeration)
 * @param[in] filter     Pointer to arc filter parameter (see #Mnt_Arc_Filter_Para_t enumeration)
 * @param[in] err_check  Pointer to arc error check parameter (see #Mnt_Arc_Err_Check_Para_t enumeration)
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_ArcPara_Cfg(Mnt_Arc_Basic_Para_t *basic, Mnt_Arc_Filter_Para_t *filter, Mnt_Arc_Err_Check_Para_t *err_check);

/**
 ****************************************************************************************
 * @brief ARC results get callback function register
 *
 * @param[in] arc_result_get_cb      ARC results get callback function
 *
 * @return None
 ****************************************************************************************
 */
void Hal_Mnt_RegisterCb(Hal_Mnt_Callback arc_result_get_cb);

/// @} HAL_MNT_API

/**
 ****************************************************************************************
 * @addtogroup HAL_TASK_API HAL TASK APIs
 * @ingroup HAL_API
 * @brief Description of HAL TASK APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Create a new task and add it to the list of tasks that are ready to run
 *
 * @param[in] pxTaskCode	Pointer to the task entry function
 * @param[in] pcName		A descriptive name for the task
 * @param[in] usStackDepth	The size of the task stack specified as the number of
 *				variables the stack can hold - not the number of bytes
 * @param[in] pvParameters	Pointer that will be used as the parameter for the task being created
 * @param[in] uxPriority	The priority at which the task should run
 * @param[out] pxCreatedTask	Used to pass back a handle by which the created task can be referenced
 *
 * @return		      pdPASS if the task was successfully created and added to a ready
 *			      list, otherwise an error code.
 *
 ****************************************************************************************
 */
#define Hal_Task_Create( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) \
	xTaskCreate( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask )

/**
 ****************************************************************************************
 * @brief Remove a task from the RTOS real time kernel's management. The task being
 * deleted will be removed from all ready, blocked, suspended and event lists
 *
 * @param[in] xTaskToDelete	   xTask The handle of the task to be deleted
 *
 * @return		      None
 *
 ****************************************************************************************
 */
#define Hal_Task_Delete( xTaskToDelete ) vTaskDelete( xTaskToDelete )

/**
 ****************************************************************************************
 * @brief Delay a task for a given number of ticks. The actual time that the task remains
 * blocked depends on the tick rate
 *
 * @param[in] xTicksToDelay	   The amount of time, in tick periods, that
 *				   the calling task should block
 *
 * @return		      None
 *
 ****************************************************************************************
 */
#define Hal_Task_Delay( xTicksToDelay ) vTaskDelay( xTicksToDelay )

/**
 ****************************************************************************************
 * @brief Suspend any task. When suspended a task will never get any microcontroller
 * processing time, no matter what its priority
 *
 * @param[in] xTaskToSuspend	    Handle to the task being suspended. Passing a NULL
 *				    handle will cause the calling task to be suspended
 *
 * @return		      None
 *
 ****************************************************************************************
 */
#define Hal_Task_Suspend( xTaskToSuspend ) vTaskSuspend( xTaskToSuspend )

/**
 ****************************************************************************************
 * @brief Suspends the scheduler without disabling interrupts.	Context switches will
 * not occur while the scheduler is suspended.
 *
 * @return		      None
 *
 ****************************************************************************************
 */
#define Hal_Task_SuspendAll( void ) vTaskSuspendAll( void )

/**
 ****************************************************************************************
 * @brief Resumes a suspended task, if the priority of the Resumed task is higher than
 * that of the current task, context switching will be performed
 *
 * @param[in] xTaskToResume	   Handle to the task being readied
 *
 * @return		      None
 *
 ****************************************************************************************
 */
#define Hal_Task_Resume( xTaskToResume ) vTaskResume( xTaskToResume )

/**
 ****************************************************************************************
 * @brief Resumes scheduler activity after it was suspended by a call to
 * Hal_Task_SuspendAll()
 *
 * @return pdTRUE means there are tasks with higher priority than the current task to be
 * resumed, and context switching is required. otherwise pdFALSE is returned
 *
 ****************************************************************************************
 */
#define Hal_Task_ResumeAll( void ) xTaskResumeAll( void )

/**
 ****************************************************************************************
 * @brief An version of Hal_Task_Resume() that can be called from within an ISR
 *
 * @param[in] xTaskToResume	   Handle to the task being readied
 *
 * @return pdTRUE means context switching needs to be performed before interrupt exit,
 * pdFALSE means no need
 *
 ****************************************************************************************
 */
#define Hal_Task_ResumeFromISR( xTaskToResume ) xTaskResumeFromISR( xTaskToResume )

/**
 ****************************************************************************************
 * @brief Starts the real time kernel tick processing. After calling the kernel
 * has control over which tasks are executed and when
 *
 * @return		      None
 *
 ****************************************************************************************
 */
#define Hal_Task_StartScheduler( void ) vTaskStartScheduler( void )


/**
 ****************************************************************************************
 * @brief Stops the real time kernel tick.  All created tasks will be automatically
 * deleted and multitasking (either preemptive or cooperative) will stop.
 *
 * @return		      None
 *
 ****************************************************************************************
 */
#define Hal_Task_EndScheduler( void ) vTaskEndScheduler( void )

/**
 ****************************************************************************************
 * @brief Forcing a context switch
 *
 * @return		      None
 *
 ****************************************************************************************
 */
#define Hal_Task_Yield( void ) taskYIELD( void )

/**
 ****************************************************************************************
 * @brief Called at the end of an ISR that can cause a context switch
 *
 * @return		      None
 *
 ****************************************************************************************
 */
#define Hal_Task_YieldFromISR( void ) taskENTER_CRITICAL_FROM_ISR( void )


/// @} HAL_TASK_API

/**
 ****************************************************************************************
 * @addtogroup HAL_FREERTOS_TIMER_API HAL FREERTOS TIMER APIs
 * @ingroup HAL_API
 * @brief Description of HAL FREERTOS TIMER APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief  Creates a new software timer instance, and returns a handle by which the created
 * software timer can be referenced
 *
 * @param[in] pcTimerName		A text name that is assigned to the timer
 * @param[in] xTimerPeriodInTicks	The timer period, The time is defined in tick periods
 * @param[in] uxAutoReload		If uxAutoReload is set to pdTRUE then the timer will expire repeatedly
 *					with a frequency set by the xTimerPeriodInTicks parameter
 * @param[in] pvTimerID 		An identifier that is assigned to the timer being created
 * @param[in] pxCallbackFunction	The function to call when the timer expires
 *
 * @return If the timer is successfully created then a handle to the newly
 * created timer is returned. If the timer cannot be created then NULL is returned
 ****************************************************************************************
 */
#define Hal_Timer_Create( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction ) \
    xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction )

/**
 ****************************************************************************************
 * @brief Starts a timer that was previously created using the HAL_TIMER_Create() API function
 *
 * @param[in] xTimer		  The handle of the timer being started/restarted
 *
 * @return pdFAIL will be returned if the command execute failed. pdPASS will
 * be returned if the command was successfully
 ****************************************************************************************
 */
#define Hal_Timer_Start(xTimer) xTimerStart( xTimer, 0 )

/**
 ****************************************************************************************
 * @brief A version of HAL_TIMER_Start() that can be called from an ISR
 *
 * @param[in] xTimer			  The handle of the timer being started/restarted
 * @param[out] pxHigherPriorityTaskWoken  pdTRUE means context switching needs to be performed
 *					  before interrupt exit, pdFALSE means no need
 *
 * @return pdFAIL will be returned if the command execute failed. pdPASS will
 * be returned if the command was successfully
 ****************************************************************************************
 */
#define Hal_Timer_StartFromISR(xTimer, pxHigherPriorityTaskWoken) xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken )

/**
 ****************************************************************************************
 * @brief Stops a timer that was previously started
 *
 * @param[in] xTimer		  The handle of the timer being stopped
 *
 * @return pdFAIL will be returned if the command execute failed. pdPASS will
 * be returned if the command was successfully
 ****************************************************************************************
 */
#define Hal_Timer_Stop(xTimer) xTimerStop( xTimer, 0 )

/**
 ****************************************************************************************
 * @brief A version of HAL_TIMER_Stop() that can be called from an ISR
 *
 * @param[in] xTimer			  The handle of the timer being stopped
 * @param[out] pxHigherPriorityTaskWoken  pdTRUE means context switching needs to be performed
 *					  before interrupt exit, pdFALSE means no need
 *
 * @return pdFAIL will be returned if the command execute failed. pdPASS will
 * be returned if the command was successfully
 ****************************************************************************************
 */
#define Hal_Timer_StopFromISR(xTimer, pxHigherPriorityTaskWoken) xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken )

/**
 ****************************************************************************************
 * @brief Re-starts a timer that was previously created using the HAL_TIMER_Create() API function.
 *
 * @param[in] xTimer		  The handle of the timer being reset/started/restarted
 *
 * @return pdFAIL will be returned if the command execute failed. pdPASS will
 * be returned if the command was successfully
 ****************************************************************************************
 */
#define Hal_Timer_Reset(xTimer) xTimerReset( xTimer, 0 )

/**
 ****************************************************************************************
 * @brief A version of HAL_TIMER_Reset() that can be called from an ISR
 *
 * @param[in] xTimer			  The handle of the timer that is to be started, reset, or restarted
 * @param[out] pxHigherPriorityTaskWoken  pdTRUE means context switching needs to be performed
 *					  before interrupt exit, pdFALSE means no need
 *
 * @return pdFAIL will be returned if the command execute failed. pdPASS will
 * be returned if the command was successfully
 ****************************************************************************************
 */
#define Hal_Timer_ResetFromISR(xTimer, pxHigherPriorityTaskWoken) xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken )

/**
 ****************************************************************************************
 * @brief Deletes a timer that was previously created using the HAL_TIMER_Create() API function.
 *
 * @param[in] xTimer		  The handle of the timer being deleted
 *
 * @return pdFAIL will be returned if the command execute failed. pdPASS will
 * be returned if the command was successfully
 ****************************************************************************************
 */
#define Hal_Timer_Delete(xTimer) xTimerDelete( xTimer, 0 )

/**
 ****************************************************************************************
 * @brief Returns the ID assigned to the timer
 *
 * @param[in] xTimer		  The timer being queried
 *
 * @return The ID assigned to the timer being queried
 ****************************************************************************************
 */
#define Hal_Timer_GetTimerID(xTimer) pvTimerGetTimerID( xTimer )

/// @} HAL_FREERTOS_TIMER_API

/**
 ****************************************************************************************
 * @addtogroup HAL_QUEUE_API HAL QUEUE APIs
 * @ingroup HAL_API
 * @brief Description of HAL QUEUE APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Creates a new queue instance, and returns a handle by which the new queue can be referenced
 *
 * @param[in] uxQueueLength	   The maximum number of items that the queue can contain
 * @param[in] uxItemSize	   The number of bytes each item in the queue will require
 *
 * @return If the queue is successfully create then a handle to the newly created queue
 * is returned. If the queue cannot be created then 0 is returned.
 *
 ****************************************************************************************
 */
#define Hal_Queue_Create( uxQueueLength, uxItemSize ) xQueueCreate( uxQueueLength, uxItemSize )

/**
 ****************************************************************************************
 * @brief Post an item to the back of a queue
 *
 * @param[in] xQueue		The handle to the queue on which the item is to be posted
 * @param[in] pvItemToQueue	pvItemToQueue A pointer to the item that is to be placed on the queue
 *
 * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
 *
 ****************************************************************************************
 */
#define Hal_Queue_Send( xQueue, pvItemToQueue ) xQueueSend( xQueue, pvItemToQueue, 0 )

/**
 ****************************************************************************************
 * @brief A version of HAL_QUEUE_Send() that can be called from an ISR
 *
 * @param[in] xQueue			  The handle to the queue on which the item is to be posted
 * @param[in] pvItemToQueue		  pvItemToQueue A pointer to the item that is to be placed on the queue
 * @param[out] pxHigherPriorityTaskWoken  pdTRUE means context switching needs to be performed
 *					  before interrupt exit, pdFALSE means no need
 *
 * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
 *
 ****************************************************************************************
 */
#define Hal_Queue_SendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \
    xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken )

/**
 ****************************************************************************************
 * @brief Post an item to the front of a queue
 *
 * @param[in] xQueue		The handle to the queue on which the item is to be posted
 * @param[in] pvItemToQueue	pvItemToQueue A pointer to the item that is to be placed on the queue
 *
 * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
 *
 ****************************************************************************************
 */
#define Hal_Queue_SendToFront( xQueue, pvItemToQueue ) xQueueSendToFront( xQueue, pvItemToQueue, 0 )

/**
 ****************************************************************************************
 * @brief A version of HAL_QUEUE_SendToFront() that can be called from an ISR
 *
 * @param[in] xQueue			  The handle to the queue on which the item is to be posted
 * @param[in] pvItemToQueue		  pvItemToQueue A pointer to the item that is to be placed on the queue
 * @param[out] pxHigherPriorityTaskWoken  pdTRUE means context switching needs to be performed
 *					  before interrupt exit, pdFALSE means no need
 *
 * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
 *
 ****************************************************************************************
 */
#define Hal_Queue_SendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \
    xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken )

/**
 ****************************************************************************************
 * @brief Receive an item from a queue, Successfully received items are removed from the queue
 *
 * @param[in] xQueue	    The handle to the queue from which the item is to be received
 * @param[out] pvBuffer     Pointer to the buffer into which the received item will be copied
 *
 * @return pdTRUE if an item was successfully received from the queue, otherwise pdFALSE.
 *
 ****************************************************************************************
 */
#define Hal_Queue_Receive( xQueue, pvBuffer ) xQueueReceive( xQueue, pvBuffer, 0 )

/**
 ****************************************************************************************
 * @brief A version of HAL_QUEUE_Receive() that can be called from an ISR
 *
 * @param[in] xQueue			  The handle to the queue from which the item is to be received
 * @param[out] pvBuffer 		  Pointer to the buffer into which the received item will be copied
 * @param[out] pxHigherPriorityTaskWoken  pdTRUE means context switching needs to be performed
 *					  before interrupt exit, pdFALSE means no need
 *
 * @return pdTRUE if an item was successfully received from the queue, otherwise pdFALSE.
 *
 ****************************************************************************************
 */
#define Hal_Queue_ReceiveFromISR( xQueue, pvBuffer, pxHigherPriorityTaskWoken ) \
    xQueueReceiveFromISR( xQueue, pvBuffer, pxHigherPriorityTaskWoken )

/**
 ****************************************************************************************
 * @brief Receive an item from a queue without removing the item from the queue
 *
 * @param[in] xQueue	    The handle to the queue from which the item is to be received
 * @param[out] pvBuffer     Pointer to the buffer into which the received item will be copied
 *
 * @return pdTRUE if an item was successfully received from the queue, otherwise pdFALSE.
 *
 ****************************************************************************************
 */
#define Hal_Queue_Peek( xQueue, pvBuffer ) xQueuePeek( xQueue, pvBuffer, 0 )

/**
 ****************************************************************************************
 * @brief A version of HAL_QUEUE_Peek() that can be called from an ISR
 *
 * @param[in] xQueue	    The handle to the queue from which the item is to be received
 * @param[out] pvBuffer     Pointer to the buffer into which the received item will be copied
 *
 * @return pdTRUE if an item was successfully received from the queue, otherwise pdFALSE.
 *
 ****************************************************************************************
 */
#define Hal_Queue_PeekFromISR( xQueue, pvBuffer ) xQueuePeekFromISR( xQueue, pvBuffer )

/**
 ****************************************************************************************
 * @brief Return the number of messages stored in a queue
 *
 * @param[in] xQueue	   A handle to the queue being queried
 *
 * @return The number of messages available in the queue.
 *
 ****************************************************************************************
 */
#define Hal_Queue_MessagesWaiting( xQueue ) uxQueueMessagesWaiting( xQueue )

/**
 ****************************************************************************************
 * @brief A version of HAL_QUEUE_MessagesWaiting() that can be called from an ISR
 *
 * @param[in] xQueue	   A handle to the queue being queried
 *
 * @return The number of messages available in the queue.
 *
 ****************************************************************************************
 */
#define Hal_Queue_MessagesWaitingFromISR( xQueue ) uxQueueMessagesWaitingFromISR( xQueue )

/// @} HAL_QUEUE_API

/**
 ****************************************************************************************
 * @addtogroup HAL_SEMAPHORE_API HAL SEMAPHORE APIs
 * @ingroup HAL_API
 * @brief Description of HAL SEMAPHORE APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Create a binary semaphore that can 'take' directly
 *
 * @param[in] xSemaphore	  Handle to the created semaphore
 *
 * @return	None.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_CreateBinary( xSemaphore )    vSemaphoreCreateBinary( xSemaphore )

/**
 ****************************************************************************************
 * @brief Creates a new counting semaphore instance, and returns a handle by which the
 * new counting semaphore can be referenced
 *
 * @param[in] uxMaxCount	  The maximum count value that can be reached.	When the
 *				  semaphore reaches this value it can no longer be 'given'
 * @param[in] uxInitialCount	  The count value assigned to the semaphore when it is created
 *
 * @return Handle to the created semaphore. Null if the semaphore could not be created.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_CreateCounting( uxMaxCount, uxInitialCount ) xSemaphoreCreateCounting( uxMaxCount, uxInitialCount )

/**
 ****************************************************************************************
 * @brief Creates a new mutex type semaphore instance, and returns a handle by which
 * the new mutex can be referenced
 *
 * @return If the mutex was successfully created then a handle to the created
 * semaphore is returned.  If there was not enough heap to allocate the mutex
 * data structures then NULL is returned.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_CreateMutex( void )    xSemaphoreCreateMutex( void )

/**
 ****************************************************************************************
 * @brief Creates a new recursive mutex type semaphore instance, and returns a handle
 * by which the new recursive mutex can be referenced.
 *
 * @return xSemaphore Handle to the created mutex semaphore.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_CreateRecursiveMutex( void )    xSemaphoreCreateRecursiveMutex( void )

/**
 ****************************************************************************************
 * @brief Obtain a binary/counting/mutex semaphore.
 *
 * @param[in] xSemaphore	  A handle to the semaphore being taken - obtained when
 *				  the semaphore was created.
 * @param[in] xBlockTime	  The time in ticks to wait for the semaphore to become available.
 *
 * @return pdTRUE if the semaphore was obtained.  pdFALSE if xBlockTime expired without
 * the semaphore becoming available.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_Take( xSemaphore, xBlockTime )    xSemaphoreTake( xSemaphore, xBlockTime )

/**
 ****************************************************************************************
 * @brief Obtain a binary/counting semaphore from an ISR.
 *
 * @param[in] xSemaphore		  A handle to the semaphore being taken.  This is the
 *					  handle returned when the semaphore was created.
 * @param[out] pxHigherPriorityTaskWoken  pdTRUE means context switching needs to be performed
 *					  before interrupt exit, pdFALSE means no need
 *
 * @return pdTRUE if the semaphore was successfully taken, otherwise pdFALSE.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_TakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) \
    xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )

/**
 ****************************************************************************************
 * @brief Obtain a recursively mutex semaphore.
 *
 * @param[in] xMutex		  A handle to the mutex being obtained.
 * @param[in] xBlockTime	  The time in ticks to wait for the semaphore to become available.
 *
 * @return pdTRUE if the semaphore was obtained.  pdFALSE if xBlockTime expired without
 * the semaphore becoming available.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_TakeRecursive( xMutex, xBlockTime )  xSemaphoreTakeRecursive( xMutex, xBlockTime )

/**
 ****************************************************************************************
 * @brief Release a binary/counting/mutex semaphore.
 *
 * @param[in] xSemaphore	  A handle to the semaphore being released.  This is the
 *				  handle returned when the semaphore was created.
 *
 * @return pdTRUE if the semaphore was released.  pdFALSE if an error occurred.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_Give( xSemaphore )    xSemaphoreGive( xSemaphore )

/**
 ****************************************************************************************
 * @brief Release a binary/counting semaphore from an ISR.
 *
 * @param[in] xSemaphore		  A handle to the semaphore being taken.  This is the
 *					  handle returned when the semaphore was created.
 * @param[out] pxHigherPriorityTaskWoken  pdTRUE means context switching needs to be performed
 *					  before interrupt exit, pdFALSE means no need
 *
 * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_GiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) \
    xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )

/**
 ****************************************************************************************
 * @brief Recursively a recursively mutex semaphore.
 *
 * @param[in] xMutex		  A handle to the mutex being released, or 'given'.
 *
 * @return pdTRUE if the semaphore was given
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_GiveRecursive( xMutex )    xSemaphoreGiveRecursive( xMutex )

/**
 ****************************************************************************************
 * @brief Delete a semaphore. This function must be used with care
 *
 * @param[in] xSemaphore	  A handle to the semaphore to be deleted
 *
 * @return	None.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_Delete( xSemaphore )    vSemaphoreDelete( xSemaphore )

/**
 ****************************************************************************************
 * @brief Returns semaphore's current count value
 *
 * @param[in] xSemaphore	  A handle to the semaphore to be deleted
 *
 * @return If the semaphore is a counting semaphore then returns its current count value.
 * If the semaphore is a binary semaphore then returns 1 if the semaphore is available,
 * and 0 if the semaphore is not available.
 *
 ****************************************************************************************
 */
#define Hal_Semaphore_GetCount( xSemaphore )    uxSemaphoreGetCount( xSemaphore )

/// @} HAL_SEMAPHORE_API

/**
 ****************************************************************************************
 * @addtogroup HAL_EVENTGROUP_API HAL EVENTGROUP APIs
 * @ingroup HAL_API
 * @brief Description of HAL EVENTGROUP APIs
 * @{
 ****************************************************************************************
 */

/*
 * API FUNCTIONS DEFINITION
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief Create a new event group
 *
 * @return If the event group was created then a handle to the event group is returned.
 * else return NULL.
 *
 ****************************************************************************************
 */
#define Hal_Eventgrp_Create( void )    xEventGroupCreate( void )

/**
 ****************************************************************************************
 * @brief Set bits within an event group
 *
 * @param[in] xEventGroup	The event group in which the bits are to be set
 * @param[in] uxBitsToSet	A bitwise value that indicates the bit or bits to set
 *
 * @return The value of the event group at the time the call to HAL_EVENTGROUP_SetBits() returns.
 *
 ****************************************************************************************
 */
#define Hal_Eventgrp_SetBits( xEventGroup, uxBitsToSet ) xEventGroupSetBits( xEventGroup, uxBitsToSet )

/**
 ****************************************************************************************
 * @brief A version of HAL_EVENTGROUP_SetBits() that can be called from an interrupt
 *
 * @param[in] xEventGroup		  The event group in which the bits are to be set
 * @param[in] uxBitsToSet		  A bitwise value that indicates the bit or bits to set
 * @param[out] pxHigherPriorityTaskWoken  pdTRUE means context switching needs to be performed
 *					  before interrupt exit, pdFALSE means no need
 *
 * @return If the request to execute the function was posted successfully then
 * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned
 * if the timer service queue was full.
 *
 ****************************************************************************************
 */
#define Hal_Eventgrp_SetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) \
    xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken)

/**
 ****************************************************************************************
 * @brief Block to wait for one or more bits to be set within a previously created event group
 *
 * @param[in] xEventGroup	The event group in which the bits are being tested
 * @param[in] uxBitsToWaitFor	A bitwise value that indicates the bit or bits to test inside the event group
 * @param[in] xClearOnExit	pdTRUE means each bits within uxBitsToWaitFor that are set within the event
 *				group will be cleared before returns, pdFALSE bits are not altered
 * @param[in] xWaitForAllBits	pdTRUE means HAL_EVENTGROUP_WaitBits() will return only when all the bits
 *				in uxBitsToWaitFor are set or the specified block time expires. pdFALSE means
 *				HAL_EVENTGROUP_WaitBits() will return when any one of the bits set in
 *				uxBitsToWaitFor is set or the specified block time expires.
 * @param[in] xTicksToWait	The maximum amount of time (specified in 'ticks') to wait for one/all (depending
				on the xWaitForAllBits value) of the bits specified by uxBitsToWaitFor to become set
 *
 * @return The value of the event group at the time either the bits being waited
 * for became set, or the block time expired.
 *
 ****************************************************************************************
 */
#define Hal_Eventgrp_WaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ) \
	xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait )

/**
 ****************************************************************************************
 * @brief Returns the current value of the bits in an event group
 *
 * @param[in] xEventGroup	The event group being queried
 *
 * @return The event group bits at the time HAL_EVENTGROUP_GetBits() was called.
 *
 ****************************************************************************************
 */
#define Hal_Eventgrp_GetBits( xEventGroup ) xEventGroupGetBits( xEventGroup )

/**
 ****************************************************************************************
 * @brief A version of HAL_EVENTGROUP_GetBits() that can be called from an interrupt
 *
 * @param[in] xEventGroup	The event group being queried
 *
 * @return The event group bits at the time HAL_EVENTGROUP_GetBitsFromISR() was called.
 *
 ****************************************************************************************
 */
#define Hal_Eventgrp_GetBitsFromISR( xEventGroup ) xEventGroupGetBitsFromISR( xEventGroup)

/**
 ****************************************************************************************
 * @brief Clear bits within an event group
 *
 * @param[in] xEventGroup	The event group in which the bits are to be cleared
 * @param[in] uxBitsToClear	A bitwise value that indicates the bit or bits to clear in the event group
 *
 * @return The value of the event group before the specified bits were cleared.
 *
 ****************************************************************************************
 */
#define Hal_Eventgrp_ClearBits( xEventGroup, uxBitsToClear ) xEventGroupClearBits( xEventGroup, uxBitsToClear )

/**
 ****************************************************************************************
 * @brief A version of HAL_EVENTGROUP_ClearBits() that can be called from an interrupt
 *
 * @param[in] xEventGroup	The event group in which the bits are to be cleared
 * @param[in] uxBitsToClear	A bitwise value that indicates the bit or bits to clear in the event group
 *
 * @return If the request to execute the function was posted successfully then
 * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned
 * if the timer service queue was full.
 *
 ****************************************************************************************
 */
#define Hal_Eventgrp_ClearBitsFromISR( xEventGroup, uxBitsToClear ) xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear )

/**
 ****************************************************************************************
 * @brief Delete an event group that was previously created
 *
 * @param[in] xEventGroup	The event group being deleted
 *
 * @return None.
 *
 ****************************************************************************************
 */
#define Hal_Eventgrp_Delete( xEventGroup )    vEventGroupDelete( xEventGroup )

/// @} HAL_EVENTGROUP_API



#ifdef __cplusplus
}
#endif

#endif /* __HAL_API_H__ */

